package com.glsc.ngateway.opmanage.service.other;


import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.util.StringUtil;
import com.glsc.ngateway.common.base.domain.mysql.gateway.other.ProductRelation;
//import com.glsc.ngateway.opmanage.domain.other.QProductRelationLog;
import com.glsc.ngateway.common.base.repo.mysql.gateway.other.ProductRelationRepository;
import com.glsc.ngateway.common.api.common.enums.DictConstant;
import com.glsc.ngateway.common.api.common.ex.GatewayException;
import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.opmanage.utils.SpecificationUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author zhouzp
 * @date 2020/5/29
 * 注意保存时，进行业务逻辑校验，校验异常直接抛异常
 */
@Service
public class ProductRelationService {

    @Resource
    private ProductRelationRepository productRelationRepository;

    @PersistenceContext
    @Qualifier("entityManagerAmProd")
    private EntityManager entityManager;

    public void save(ProductRelation relation) {
        valid(relation);//保存数据校验，不合法则直接抛异常

        productRelationRepository.save(relation);
    }

    public void saveAll(List<ProductRelation> productRelationList) {
        productRelationRepository.saveAll(productRelationList);
    }

    /**
     * 分页条件查询
     *
     * @param pageNo
     * @param pageSize
     * @param param
     * @return
     */
    public Page<ProductRelation> findPage(int pageNo, int pageSize, Map<String, Object> param) {
        Sort.Direction direction = Sort.Direction.DESC;
        String sort = "relationId";

        pageNo= PageUtil.initPageNo(pageNo);
        pageSize=PageUtil.initPageSize(pageSize);

        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, direction, sort);
        return productRelationRepository.findAll(SpecificationUtil.buildSpecification(param, ProductRelation.class), pageable);
    }

    /**
     * 根据条件查询List
     */
    public List<ProductRelation> findList(Map<String, Object> param) {
        return productRelationRepository.findAll(SpecificationUtil.buildSpecification(param, ProductRelation.class));
    }

    /**
     * 根据ID查询
     *
     * @return
     */
    public ProductRelation findById(Integer id) {
        Optional<ProductRelation> optional = productRelationRepository.findById(id);

        if (optional.isPresent()) {
            return optional.get();
        } else {
            return null;
        }
    }

    public void valid(ProductRelation relation) {

        if (null == relation || null == relation.getRelationType()|| StringUtils.isEmpty(relation.getRelatedId())
        ) {
            throw GatewayException.error("产品干系人，必要业务要素填写不全！" + relation.toString());
        }

        //业务逻辑校验
        switch (relation.getRelationType()) {
            case "INVEST_MANAGER"://投资经理则必须填写生效日
                if (StringUtil.isEmpty(relation.getEffectiveDate())
                ) {
                    throw GatewayException.error("投资经理，必要业务要素填写不全，投资经理生效日期为空！" + relation.toString());
                }
                break;
            case "CONTRACTOR"://这四个需要分成比例
            case "CONTRACT_DEPARTMENT":
            case "REVENUE_DEPARTMENT":
            case "SCALE_DEPARTMENT":
                if (null == relation.getProdPercent()
                ) {
                    throw GatewayException.error("收入规模，必要业务要素填写不全，缺少分成比例！" + relation.toString());
                }
                break;
            default:
                break;
        }
    }

//    public Object logPage(String prodId, int pageNo, int pageSize) {
//        QProductRelationLog qProductRelationLog = QProductRelationLog.productRelationLog;
//        BooleanBuilder where = new BooleanBuilder();
//        if (!StrUtil.isBlank(prodId)) {
//            where = where.and(qProductRelationLog.prodId.eq(Integer.valueOf(prodId)));
//        }
//
//        Pageable pageable = PageRequest.of(pageNo - 1, pageSize);
//
//        JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
//        JPAQuery<ProductRelationLog> query = queryFactory.select(qProductRelationLog)
//                .from(qProductRelationLog)
//                .where(where)
//                .orderBy(qProductRelationLog.logId.desc())
//                .offset(pageable.getOffset())
//                .limit(pageable.getPageSize());
//        return query.fetchResults();
//    }

    /**
     * 根据ID查询
     */
    public void deleteById(Integer id) {
        productRelationRepository.deleteById(id);
    }

    /**
     * 修改投资经理、投资助理生效日为空的数据为产品成立日
     * @param prodId
     * @param prodStartDate
     * @param relationTypeList
     */
    public Integer update(Integer prodId,String prodStartDate,List<String> relationTypeList) {
        return productRelationRepository.updateEffectiveDateByProdId(prodId,prodStartDate,relationTypeList);
    }

    /**
     * 根据prodId设置为已删除标记
     *
     * @return
     */
    @Transactional
    public void updateDeletedById(Integer prodId,List<String> relationTypeList) {
        List<ProductRelation> productRelationList = productRelationRepository.findListByProdIdAndRelationTypeList(prodId, relationTypeList, DictConstant.NO);
        if(!CollectionUtils.isEmpty(productRelationList)){
            productRelationList.forEach(productRelation -> {
                productRelation.setDeleted(DictConstant.YES);
            });
            productRelationRepository.saveAll(productRelationList);
        }
    }

    /**
     * 根据prodId设置为已删除标记
     *
     * @return
     */
    @Transactional
    public void updateDeletedByKeyId(Integer keyId,List<String> relationTypeList) {
        List<ProductRelation> productRelationList = productRelationRepository.findAllByKeyIdAndRelationTypeInAndDeleted(keyId, relationTypeList,DictConstant.NO);
        if(!CollectionUtils.isEmpty(productRelationList)){
            productRelationList.forEach(productRelation -> {
                productRelation.setDeleted(DictConstant.YES);
            });
            productRelationRepository.saveAll(productRelationList);
        }
    }

    @Transactional
    public void updateDeletedBySeriesId(Integer seriesId,List<String> relationTypeList) {
        List<ProductRelation> productRelationList = productRelationRepository.findAllBySeriesIdAndRelationTypeInAndDeleted(seriesId, relationTypeList,DictConstant.NO);
        if(!CollectionUtils.isEmpty(productRelationList)){
            productRelationList.forEach(productRelation -> {
                productRelation.setDeleted(DictConstant.YES);
            });
            productRelationRepository.saveAll(productRelationList);
        }
    }

    public List<ProductRelation> findListByProdIdAndRelationTypeList(Integer prodId,List<String> relationTypeList){
        List<ProductRelation> productRelationList = productRelationRepository.findListByProdIdAndRelationTypeList(prodId, relationTypeList,DictConstant.NO);
        return productRelationList;
    }

    public List<ProductRelation> findListBySeriesIdAndRelationTypeList(Integer seriesId,List<String> relationTypeList){
        List<ProductRelation> productRelationList = productRelationRepository.findListBySeriesIdAndRelationTypeList(seriesId, relationTypeList,DictConstant.NO);
        return productRelationList;
    }

    public List<ProductRelation> findListByKeyIdList(List<Integer> ketIdList){
        if(CollectionUtil.isEmpty(ketIdList)){
            return new ArrayList<>();
        }
        List<ProductRelation> productRelationList = productRelationRepository.findAllByKeyIdInAndDeleted(ketIdList,DictConstant.NO);
        return productRelationList;
    }

    public List<ProductRelation> findListByKeyIdAndRelationTypeList(Integer keyId,List<String> relationTypeList){
        List<ProductRelation> productRelationList = productRelationRepository.findAllByKeyIdAndRelationTypeInAndDeleted(keyId, relationTypeList,DictConstant.NO);
        return productRelationList;
    }
}
